package com.crm.service.impl;

import com.crm.service.IUserService;
import com.crm.service.utils.MsgDigest;
import com.crm.service.utils.ServiceUtils;
import com.crm.dao.IUserDao;
import com.crm.model.User;

import java.util.List;
import java.util.Date;

/**
 * 用户管理的业务逻辑类。提供登录用户的检测、创建新帐号、修改帐号密码等功能。
 *
 * @author <a href="mailto:huang0510@hotmail.com">HuangHuang</a>
 * @version $Id$
 */
public class UserService implements IUserService {

    /**
     * 内置超级管理员的帐号，用于初始化
     */
    private static final String SUPER_ADMIN = "administrator";

    /**
     * 内置超级管理员帐号初始密码,admin@123
     */
    private static final String SUPER_ADMIN_PWD = "e6e061838856bf47e1de730719fb2609";

    /**
     * 创建新用户的初始密码
     */
    private static final String DEFAULT_PWD = "123456";

    private IUserDao userDao;

    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * 创建一个新用户。调用该服务需要传入一个用户实例。如果相同的用户名和密码已经
     * 存在，则新用户不能被创建。
     *
     * @param user 用户实例
     * @return 创建成功返回true，用户已经存在返回false
     */
    public boolean createUser(User user) {
        boolean isOk = true;
        String u = ServiceUtils.convertNull(user.getUsername());
        String t = ServiceUtils.convertNull(user.getTruename());

        if (User.GROUP_SUPER.equals(user.getUserGroup()) && 
                userDao.getUserByGroup(User.GROUP_SUPER).size() >= 2) {
            throw new UnsupportedOperationException("超过超级管理员用户数限制！");
        }

        if ("".equals(u) || "".equals(t)) {
            throw new NullPointerException("没有指定用户名或真实姓名！");
        } else {
            user.setPassword(MsgDigest.getSHA(DEFAULT_PWD));
        }

        String p = ServiceUtils.convertNull(user.getPassword());
        if (getUserByNameAndPwd(u, p) != null) {
            isOk = false;
        } else {
            userDao.save(user);
        }

        return isOk;
    }

    /**
     * 修改一个用户。
     *
     * @param user 用户实例，该用户的属性被改变。
     * @return 修改成功返回true。
     */
    public boolean alterUser(User user) {
        User oldUser = userDao.getUserById(user.getId());
        if (oldUser == null) {
            throw new NullPointerException("要修改的用户不存在！");
        }
        userDao.save(user);

        return true;
    }

    /**
     * {@inheritDoc}
     */
    public List<User> getUsers() {
        return userDao.getUsers();
    }

    /**
     * {@inheritDoc}
     */
    public List getUsersExceptSomebody(User user) {
        return userDao.getUsersExceptSomebody(user.getUserCode());
    }

    /**
     * {@inheritDoc}
     */
    public User getUserById(String id) {
        return userDao.getUserById(id);
    }

    /**
     * {@inheritDoc}
     */
    public User getUserByCode(String code) {
        return userDao.getUserByCode(code);
    }

    /**
     * {@inheritDoc}
     */
    public List getUserByGroup(String userGroup) {
        return userDao.getUserByGroup(userGroup);
    }

    /**
     * 检测登录用户是否存在，使用内置的超级管理员帐号第一次登录时，自动初始化。
     *
     * @param u 用户名
     * @param p 密码
     * @return 若用户存在返回User实例，若不存在则返回的是null
     */
    public User getUserByNameAndPwd(String u, String p) {
        String psw = MsgDigest.getSHA(p);
        User user = userDao.getUserByNameAndPwd(u, psw);
        int suNum = userDao.getUserByGroup(User.GROUP_SUPER).size();
        if (user == null && SUPER_ADMIN.equals(u) && SUPER_ADMIN_PWD.equals(psw) && suNum < 2) {
            User su = new User();
            su.setUsername(u);
            su.setPassword(psw);
            su.setUserGroup(User.GROUP_SUPER);
            su.setUserCode(generateUserCode());
            userDao.save(su);
            user = su;
        }
        return user;
    }

    /**
     * {@inheritDoc}
     */
    public String generateUserCode() {
        return generateUserCode0();
    }

    /**
     * {@inheritDoc}
     */
    public void deleteUser(User u) {
        userDao.delete(u);
    }

    private synchronized String generateUserCode0() {
        String uc = ServiceUtils.formatDate(new Date(), ServiceUtils.FORMAT_USER_CODE);
        String maxUC = userDao.getMaxUserCode();
        String suffix = "0001";
        if (maxUC != null) {
            suffix = incrementUserCode(maxUC);
        }
        return uc + suffix;
    }

    private String incrementUserCode(String code) {
        if (code.length() == 16) {
            code = code.substring(code.length() - 4);
        }
        int oldUserSeq = Integer.parseInt(code);
        int newUserSeq = oldUserSeq + 1;
        code = "000" + newUserSeq;
        return code.substring(code.length() - 4);
    }
}
